<?php

class loClassAction extends runtAction
{
    /**
     * @var Match
     */
    public $match;
    /**
     * @var Match
     */
    public $oldMatch;

    public function initAction()
    {

        $match = c('redis')->get('match');
        if (!empty($match)) {
            $match = unserialize($match);
        } else {
            $match = new Match();
        }
        $this->match = $match;
        //初始值
        $this->oldMatch = clone $this->match;
    }

    public function testAction()
    {

//        $this->match->p1->ap  = 3;
//        $this->match->p2->any = 8;
//        //AF
//        $this->match->p1->map[0][0] = new Card(3, 1, 1);
//        $this->match->p1->map[0][1] = new Card(3, 1, 2);
//        $this->match->p1->map[0][2] = new Card(3, 1, 1);
//        //DF
//        $this->match->p1->map[1][1] = new Card(0, 3, 3, 1);
//
//        //dAF
//        $this->match->p2->map[0][1] = new Card(3, 1, 2, 1);
//        //dDF
//        $this->match->p2->map[1][1] = new Card(0, 2, 3, 1);
//
//        $this->tryDo(0, 0);
//        $this->tryDo(1, 0);
//        $this->resetPoint();
//
//        echo (string)$this->match;
//        $this->tryDo(1, 1);
//        echo (string)$this->match;
//        $_SESSION['match'] = $this->match;
        echo $this->match;
        exit();
    }

    public function resetPoint()
    {
        $this->match->p1 = $this->oldMatch->p1;
        $this->match->p2 = $this->oldMatch->p2;
    }

    public function tryDo($x = 0, $y = 0)
    {
        echo ($x == 0) ? 'left' : ($x == 1 ? 'center' : 'right');
        echo ($y == 0) ? 'AF' : 'DF';
        $res = $this->match->match($x, $y);
        if ($res['in']) {
            echo ":in\n";
        } else {
            $res['kill'] = $res['kill'] ? 'y' : 'n';
            $res['down'] = $res['down'] ? 'n' : 'y';
            echo ":kill_{$res['kill']};live_{$res['down']} \n";
        }
    }
}

class Match
{
    /**
     * @var Player
     */
    public $p1;
    /**
     * @var Player
     */
    public $p2;

    public function __construct()
    {
        $this->p1 = new Player();
        $this->p2 = new Player();
    }

    /**
     * @param $x
     * @param $y
     * @param $type int 策略
     * 策略0：先用点,后用支援;能活着先活着,而后能打死就打死;达不成不用
     * @return array
     */
    public function match($x = 0, $y = 0, $type = 0)
    {
        $target           = $this->p1->map[$y][$x];
        $ap               = $target->ap;
        $dp               = $target->dp;
        $supportTargetArr = [];
        $tmp              = $this->p1->map[abs($y - 1)][$x];
        $consume          = [];
        $dConsume         = [];

        $dTarget = $this->p2->map[abs($y - 1)][$x];
        $kill    = true;
        $down    = false;
        $in      = false;
        //抵消操作
        while ($this->p1->ap > 0 && $this->p2->dp > 0) {
            $this->p1->ap--;
            $consume['ap']++;
            $this->p2->dp--;
            $dConsume['dp']++;
        }

        if (empty($target) || $target->trip || empty($dTarget) || $dTarget->trip) {
            $in = true;
            return [
                'kill'     => $kill,
                'down'     => $down,
                'in'       => $in,
                'consume'  => $consume,
                'dConsume' => $dConsume
            ];
        }
        $target->trip = true;

        $dAp           = $dTarget->ap;
        $dDp           = $dTarget->dp;
        $dTarget->trip = true;


        if ($tmp != null && $tmp->trip === false) {
            $supportTargetArr[] = $tmp;
        }
        $tmp = isset($this->p1->map[$y][$x - 1]) ? $this->p1->map[$y][$x - 1] : null;
        if ($tmp != null && $tmp->trip === false) {
            $supportTargetArr[] = $tmp;
        }

        $tmp = isset($this->p1->map[$y][$x + 1]) ? $this->p1->map[$y][$x + 1] : null;
        if ($tmp != null && $tmp->trip === false) {
            $supportTargetArr[] = $tmp;
        }


        if ($dp < $dAp) {
            $tP1 = clone $this->p1;
            $tP2 = clone $this->p2;
            while (1) {
                if ($tP1->dp > 0) {
                    $tP1->dp--;
                    $dp++;
                    $consume['dp']++;
                } else if ($tP1->any > 0) {
                    $tP1->any--;
                    $dp++;
                    $consume['any']++;
                } else if ($y == 1 && $dp < $dAp && !empty($supportTargetArr)) {
                    $dp                        += $supportTargetArr[0]->sp;
                    $supportTargetArr[0]->trip = true;
                    unset($supportTargetArr[0]);
                    $supportTargetArr = array_values($supportTargetArr);
                } else if ($dp >= $dAp) {
                    if ($tP2->ap > 0) {
                        $tP2->ap--;
                        $dAp++;
                        $dConsume['ap']++;
                    } else if ($tP2->any > 0) {
                        $tP2->any--;
                        $dAp++;
                        $dConsume['any']++;
                    } else {
                        $this->p1 = $tP1;
                        $down     = false;
                        break;
                    }
                } else {
                    $this->p2 = $tP2;
                    $down     = true;
                    break;
                }
            }
        }

        if ($ap <= $dDp) {
            $tP1 = clone $this->p1;
            $tP2 = clone $this->p2;

            while (1) {
                if ($tP1->ap > 0) {
                    $tP1->ap--;
                    $ap++;
                    $consume['ap']++;
                } else if ($tP1->any > 0) {
                    $tP1->any--;
                    $ap++;
                    $consume['any']++;
                } else if ($y == 0 && $ap <= $dDp && !empty($supportTargetArr)) {
                    $ap                        += $supportTargetArr[0]->sp;
                    $supportTargetArr[0]->trip = true;
                    unset($supportTargetArr[0]);
                    $supportTargetArr = array_values($supportTargetArr);
                } else if ($ap > $dDp) {
                    if ($tP2->dp > 0) {
                        $tP2->dp--;
                        $dDp++;
                        $dConsume['dp']++;
                    } else if ($tP2->any > 0) {
                        $tP2->any--;
                        $dDp++;
                        $dConsume['any']++;
                    } else {
                        $this->p1 = $tP1;
                        $kill     = true;
                        break;
                    }
                } else {
                    $this->p2 = $tP2;
                    $kill     = false;
                    break;
                }
            }
        }

        return [
            'kill'     => $kill,
            'down'     => $down,
            'in'       => $in,
            'consume'  => $consume,
            'dConsume' => $dConsume
        ];
    }

    /**
     * @return string
     */
    public function __toString()
    {
        return "--------------------------------\n"
            . "[{$this->p2->map[1][0]}]|[{$this->p2->map[1][1]}]|[{$this->p2->map[1][2]}]\n"
            . "[{$this->p2->map[0][0]}]|[{$this->p2->map[0][1]}]|[{$this->p2->map[0][2]}]\n"
            . "--------------------------------\n"
            . "--------------------------------\n"
            . "[{$this->p1->map[0][0]}]|[{$this->p1->map[0][1]}]|[{$this->p1->map[0][2]}]\n"
            . "[{$this->p1->map[1][0]}]|[{$this->p1->map[1][1]}]|[{$this->p1->map[1][2]}]\n"
            . "--------------------------------\n";
    }
}


class Player
{

    public $map = [
        0 => [
            0 => null,
            1 => null,
            2 => null
        ],
        1 => [
            0 => null,
            1 => null,
            2 => null
        ],
    ];
    public $ap  = 0;
    public $dp  = 0;
    public $sp  = 0;
    /**
     * @var int ap|dp
     */
    public $any = 0;

    public function __construct()
    {
        foreach ($this->map as $lk => $line) {
            foreach ($line as $k => $card) {
                $this->map[$lk][$k] = new NoCard();
            }
        }
    }
}

class NoCard
{
    public function __toString()
    {
        return "     ";
    }
}

class Card
{
    public $ap      = 0;
    public $dp      = 0;
    public $sp      = 0;
    public $support = 0;
    public $trip    = false;

    public function __construct($ap = 0, $dp = 0, $sp = 0, $support = 0)
    {
        $this->ap = $ap;
        $this->dp = $dp;
        $this->sp = $sp;
    }

    public function __toString()
    {
        if ($this->trip) {
            return '>>T<<';
        } else {
            return "{$this->ap}|{$this->dp}|{$this->sp}";
        }
    }
}